﻿using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text.RegularExpressions;
using UnityEditor;

public class HK_DebugToolEditor
{
    static HK_DebugToolEditor m_Instance;
    public static HK_DebugToolEditor GetInstacne()
    {
        if (m_Instance == null)
        {
            m_Instance = new HK_DebugToolEditor();
        }
        return m_Instance;
    }

    const string DEBUGERFILEPATH = "Assets/HKTools/ForRuntime/9.HK_DebugTool/Scripts/HK_DebugTool.cs";
    int m_DebugerFileInstanceId;
    Type m_ConsoleWindowType = null;
    FieldInfo m_ActiveTextInfo;
    FieldInfo m_ConsoleWindowFileInfo;

    HK_DebugToolEditor()
    {
        UnityEngine.Object debuggerFile = AssetDatabase.LoadAssetAtPath(DEBUGERFILEPATH, typeof(UnityEngine.Object));
        m_DebugerFileInstanceId = debuggerFile.GetInstanceID();
        m_ConsoleWindowType = Type.GetType("UnityEditor.ConsoleWindow,UnityEditor");
        m_ActiveTextInfo = m_ConsoleWindowType.GetField("m_ActiveText", BindingFlags.Instance | BindingFlags.NonPublic);
        m_ConsoleWindowFileInfo = m_ConsoleWindowType.GetField("ms_ConsoleWindow", BindingFlags.Static | BindingFlags.NonPublic);
    }

    [UnityEditor.Callbacks.OnOpenAssetAttribute(-1)]
    static bool OnOpenAsset(int instanceID, int line)
    {
        if (instanceID == HK_DebugToolEditor.GetInstacne().m_DebugerFileInstanceId)
        {
            return HK_DebugToolEditor.GetInstacne().FindCode();
        }
        return false;
    }

    bool FindCode()
    {
        var windowInstance = m_ConsoleWindowFileInfo.GetValue(null);
        var activeText = m_ActiveTextInfo.GetValue(windowInstance);
        string[] contentStrings = activeText.ToString().Split('\n');
        List<string> filePath = new List<string>();
        for (int index = 0; index < contentStrings.Length; index++)
        {
            if (contentStrings[index].Contains("at"))
            {
                filePath.Add(contentStrings[index]);
            }
        }
        bool success = PingAndOpen(filePath[1]);
        return success;
    }

    bool PingAndOpen(string fileContext)
    {
        string regexRule = @"at ([\w\W]*):(\d+)\)";
        Match match = Regex.Match(fileContext, regexRule);
        if (match.Groups.Count > 1)
        {
            string path = match.Groups[1].Value;
            string line = match.Groups[2].Value;
            UnityEngine.Object codeObject = AssetDatabase.LoadAssetAtPath(path, typeof(UnityEngine.Object));
            if (codeObject == null)
            {
                return false;
            }
            EditorGUIUtility.PingObject(codeObject);
            AssetDatabase.OpenAsset(codeObject, int.Parse(line));
            return true;
        }
        return false;
    }
}
